package com.bestcem.xm.common.core.config.delaymq.util;

import cn.hutool.core.date.DateUtil;
import com.bestcem.xm.componet.redis.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author sh.pei <sh.pei@idiaoyan.com>
 * @version v1.0
 * @date 2022/1/13 16:23
 */
@Component
@Slf4j
public class DelayMqUtil {

    @Value("${app.mq.delayMqRedisKeyFormat:xm_ds:%s:delay_queue}")
    private String delayMqRedisKeyFormat;

    @Value("${spring.application.name}")
    private String applicationName;

    @Value("${app.mq.delayRetryCount:5}")
    private int delayRetryCount;

    @Resource
    private RedisService redisService;

    /**
     * 延迟时间 计算score 基准线
     */
    private static final long DELAY_BASELINE_TIME = DateUtil.parseDateTime("2023-01-01 00:00:00").getTime();

    /**
     * 计算 redis 延迟zset的score
     *
     * @param delayDate
     * @return
     */
    public double getScore(Date delayDate) {
        return delayDate.getTime() - DELAY_BASELINE_TIME;
    }

    /**
     * 将消息id加入redis的zset
     *
     * @param id        消息id
     * @param delayDate 延迟时间
     */
    public void addToRedis(String id, Date delayDate) {
        redisService.zSetAdd(getDelayMqRedisKey(), id, getScore(delayDate));
    }

    /**
     * 查询延迟队列
     *
     * @param min 最小
     * @param max 最大
     * @return
     */
    public Set<String> rangeByScore(double min, double max) {

        Long count = redisService.zSetCount(getDelayMqRedisKey(), min, max);
        if (count == 0) {
            return new HashSet<>();
        } else {
            return redisService.zsetRangeByScore(getDelayMqRedisKey(), min, max, 0, Math.min(count, 10000)).stream().map(Object::toString).collect(Collectors.toSet());
        }

    }

    /**
     * 从延迟队列删除id
     *
     * @param id 消息id
     * @return
     */
    public long removeId(String id) {
        return redisService.zsetRemove(getDelayMqRedisKey(), id);
    }

    /**
     * 将消息id加入redis的zset
     *
     * @param tuples
     */
    public void addToRedis(Set<ZSetOperations.TypedTuple<Object>> tuples) {
        redisService.zSetAdd(getDelayMqRedisKey(), tuples);
    }

    public int getDelayRetryCount() {
        return delayRetryCount;
    }


    public String getDelayMqRedisKey() {
        return String.format(delayMqRedisKeyFormat, applicationName);
    }
}
